#include <stdio.h>
#include <stdarg.h>

#ifdef NCURSES
# include "host/ncurses.h"
#endif

#ifndef NOGUI
# include "gui/logwin.h"
#endif

#include "core.h"
#include "log.h"
#include "thread.h"

char *dbgTypeName[] =
{
    "CORE",
    "CPU",
    "ELF",
    "FS",
    "GFX",
    "HARDWARE",
    "HLE",
    "LOADER",
    "MEMMAP",
    "THREAD",
    "VFPU",
    "AUDIO"
};

char *dbgLvlName[] =
{
    "ERROR",
    "WARNING",
    "INFO",
    "DEBUG",
    "TRACE",
    "FULL"
};

DbgLvl debug_level = INF;

#ifdef UNIX
# define COLOR(color) "\033["color"m"
# define RED    COLOR("31;1")
# define YELLOW COLOR("33;1")
# define WHITE  COLOR("0;1")
# define CLEAR  COLOR("0")
#endif

#ifndef NO_THREAD
Mutex logMtx;
#endif

void logInitTh()
{
#ifndef NO_THREAD
    cs_init(&logMtx, "Logging");
#endif
}

void logFreeTh()
{
#ifndef NO_THREAD
    cs_free(&logMtx);
#endif
}

void _log(DbgLvl lvl, DbgType cat, const char *fmt, ...)
{
    va_list ap;
    if (debug_level < lvl)
        return;
    cs_enter(&logMtx);
    va_start(ap, fmt);
#ifndef NOGUI
    logwin_log(lvl, cat, fmt, ap);
#else
# ifdef NCURSES
    if (isDbg)
        ncurses_dbg(lvl, fmt, ap);
    else
    {
# endif
# ifdef UNIX
        switch (lvl)
        {
        case ERR:
            printf("%s", RED);
            break;

        case WRN:
            printf("%s", YELLOW);
            break;

        case INF:
        case DBG:
            printf("%s", WHITE);
            break;

        default:
            printf("%s", CLEAR);
            break;
        }
# endif
        printf("%s: ", dbgTypeName[cat]);
        vprintf(fmt, ap);
        printf("\n");
# ifdef NCURSES
    }
# endif
#endif
    cs_leave(&logMtx);
    va_end(ap);
}

